home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / dns / resolver.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2008-10-13  |  13.7 KB  |  599 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. import socket
  5. import sys
  6. import time
  7. import dns.exception as dns
  8. import dns.message as dns
  9. import dns.name as dns
  10. import dns.query as dns
  11. import dns.rcode as dns
  12. import dns.rdataclass as dns
  13. import dns.rdatatype as dns
  14. if sys.platform == 'win32':
  15.     import _winreg
  16.  
  17.  
  18. class NXDOMAIN(dns.exception.DNSException):
  19.     pass
  20.  
  21. Timeout = dns.exception.Timeout
  22.  
  23. class NoAnswer(dns.exception.DNSException):
  24.     pass
  25.  
  26.  
  27. class NoNameservers(dns.exception.DNSException):
  28.     pass
  29.  
  30.  
  31. class NotAbsolute(dns.exception.DNSException):
  32.     pass
  33.  
  34.  
  35. class NoRootSOA(dns.exception.DNSException):
  36.     pass
  37.  
  38.  
  39. class Answer(object):
  40.     
  41.     def __init__(self, qname, rdtype, rdclass, response):
  42.         self.qname = qname
  43.         self.rdtype = rdtype
  44.         self.rdclass = rdclass
  45.         self.response = response
  46.         min_ttl = -1
  47.         rrset = None
  48.         for count in xrange(0, 15):
  49.             
  50.             try:
  51.                 rrset = response.find_rrset(response.answer, qname, rdclass, rdtype)
  52.                 if min_ttl == -1 or rrset.ttl < min_ttl:
  53.                     min_ttl = rrset.ttl
  54.                 
  55.             continue
  56.             except KeyError:
  57.                 if rdtype != dns.rdatatype.CNAME:
  58.                     
  59.                     try:
  60.                         crrset = response.find_rrset(response.answer, qname, rdclass, dns.rdatatype.CNAME)
  61.                         if min_ttl == -1 or crrset.ttl < min_ttl:
  62.                             min_ttl = crrset.ttl
  63.                         
  64.                         for rd in crrset:
  65.                             qname = rd.target
  66.                         
  67.                     except KeyError:
  68.                         raise NoAnswer
  69.                     except:
  70.                         None<EXCEPTION MATCH>KeyError
  71.                     
  72.  
  73.                 None<EXCEPTION MATCH>KeyError
  74.                 raise NoAnswer
  75.                 continue
  76.             
  77.  
  78.         
  79.         if rrset is None:
  80.             raise NoAnswer
  81.         
  82.         self.rrset = rrset
  83.         self.expiration = time.time() + min_ttl
  84.  
  85.     
  86.     def __getattr__(self, attr):
  87.         if attr == 'name':
  88.             return self.rrset.name
  89.         elif attr == 'ttl':
  90.             return self.rrset.ttl
  91.         elif attr == 'covers':
  92.             return self.rrset.covers
  93.         elif attr == 'rdclass':
  94.             return self.rrset.rdclass
  95.         elif attr == 'rdtype':
  96.             return self.rrset.rdtype
  97.         else:
  98.             raise AttributeError, attr
  99.  
  100.     
  101.     def __len__(self):
  102.         return len(self.rrset)
  103.  
  104.     
  105.     def __iter__(self):
  106.         return iter(self.rrset)
  107.  
  108.     
  109.     def __getitem__(self, i):
  110.         return self.rrset[i]
  111.  
  112.     
  113.     def __delitem__(self, i):
  114.         del self.rrset[i]
  115.  
  116.     
  117.     def __getslice__(self, i, j):
  118.         return self.rrset[i:j]
  119.  
  120.     
  121.     def __delslice__(self, i, j):
  122.         del self.rrset[i:j]
  123.  
  124.  
  125.  
  126. class Cache(object):
  127.     
  128.     def __init__(self, cleaning_interval = 300):
  129.         self.data = { }
  130.         self.cleaning_interval = cleaning_interval
  131.         self.next_cleaning = time.time() + self.cleaning_interval
  132.  
  133.     
  134.     def maybe_clean(self):
  135.         now = time.time()
  136.         if self.next_cleaning <= now:
  137.             keys_to_delete = []
  138.             for k, v in self.data.iteritems():
  139.                 if v.expiration <= now:
  140.                     keys_to_delete.append(k)
  141.                     continue
  142.             
  143.             for k in keys_to_delete:
  144.                 del self.data[k]
  145.             
  146.             now = time.time()
  147.             self.next_cleaning = now + self.cleaning_interval
  148.         
  149.  
  150.     
  151.     def get(self, key):
  152.         self.maybe_clean()
  153.         v = self.data.get(key)
  154.         if v is None or v.expiration <= time.time():
  155.             return None
  156.         
  157.         return v
  158.  
  159.     
  160.     def put(self, key, value):
  161.         self.maybe_clean()
  162.         self.data[key] = value
  163.  
  164.     
  165.     def flush(self, key = None):
  166.         if key is not None:
  167.             if self.data.has_key(key):
  168.                 del self.data[key]
  169.             
  170.         else:
  171.             self.data = { }
  172.             self.next_cleaning = time.time() + self.cleaning_interval
  173.  
  174.  
  175.  
  176. class Resolver(object):
  177.     
  178.     def __init__(self, filename = '/etc/resolv.conf', configure = True):
  179.         self.reset()
  180.         if configure:
  181.             if sys.platform == 'win32':
  182.                 self.read_registry()
  183.             elif filename:
  184.                 self.read_resolv_conf(filename)
  185.             
  186.         
  187.  
  188.     
  189.     def reset(self):
  190.         self.domain = dns.name.Name(dns.name.from_text(socket.gethostname())[1:])
  191.         if len(self.domain) == 0:
  192.             self.domain = dns.name.root
  193.         
  194.         self.nameservers = []
  195.         self.search = []
  196.         self.port = 53
  197.         self.timeout = 2
  198.         self.lifetime = 30
  199.         self.keyring = None
  200.         self.keyname = None
  201.         self.edns = -1
  202.         self.ednsflags = 0
  203.         self.payload = 0
  204.         self.cache = None
  205.  
  206.     
  207.     def read_resolv_conf(self, f):
  208.         if isinstance(f, str) or isinstance(f, unicode):
  209.             
  210.             try:
  211.                 f = open(f, 'r')
  212.             except IOError:
  213.                 self.nameservers = [
  214.                     '127.0.0.1']
  215.                 return None
  216.  
  217.             want_close = True
  218.         else:
  219.             want_close = False
  220.         
  221.         try:
  222.             for l in f:
  223.                 if len(l) == 0 and l[0] == '#' or l[0] == ';':
  224.                     continue
  225.                 
  226.                 tokens = l.split()
  227.                 if len(tokens) == 0:
  228.                     continue
  229.                 
  230.                 if tokens[0] == 'nameserver':
  231.                     self.nameservers.append(tokens[1])
  232.                     continue
  233.                 if tokens[0] == 'domain':
  234.                     self.domain = dns.name.from_text(tokens[1])
  235.                     continue
  236.                 if tokens[0] == 'search':
  237.                     for suffix in tokens[1:]:
  238.                         self.search.append(dns.name.from_text(suffix))
  239.                     
  240.         finally:
  241.             if want_close:
  242.                 f.close()
  243.             
  244.  
  245.         if len(self.nameservers) == 0:
  246.             self.nameservers.append('127.0.0.1')
  247.         
  248.  
  249.     
  250.     def _determine_split_char(self, entry):
  251.         if entry.find(' ') >= 0:
  252.             split_char = ' '
  253.         elif entry.find(',') >= 0:
  254.             split_char = ','
  255.         else:
  256.             split_char = ' '
  257.         return split_char
  258.  
  259.     
  260.     def _config_win32_nameservers(self, nameservers):
  261.         nameservers = str(nameservers)
  262.         split_char = self._determine_split_char(nameservers)
  263.         ns_list = nameservers.split(split_char)
  264.         for ns in ns_list:
  265.             if ns not in self.nameservers:
  266.                 self.nameservers.append(ns)
  267.                 continue
  268.         
  269.  
  270.     
  271.     def _config_win32_domain(self, domain):
  272.         self.domain = dns.name.from_text(str(domain))
  273.  
  274.     
  275.     def _config_win32_search(self, search):
  276.         search = str(search)
  277.         split_char = self._determine_split_char(search)
  278.         search_list = search.split(split_char)
  279.         for s in search_list:
  280.             if s not in self.search:
  281.                 self.search.append(dns.name.from_text(s))
  282.                 continue
  283.         
  284.  
  285.     
  286.     def _config_win32_fromkey(self, key):
  287.         
  288.         try:
  289.             (servers, rtype) = _winreg.QueryValueEx(key, 'NameServer')
  290.         except WindowsError:
  291.             servers = None
  292.  
  293.         if servers:
  294.             self._config_win32_nameservers(servers)
  295.             
  296.             try:
  297.                 (dom, rtype) = _winreg.QueryValueEx(key, 'Domain')
  298.                 if dom:
  299.                     self._config_win32_domain(servers)
  300.             except WindowsError:
  301.                 pass
  302.             except:
  303.                 None<EXCEPTION MATCH>WindowsError
  304.             
  305.  
  306.         None<EXCEPTION MATCH>WindowsError
  307.         
  308.         try:
  309.             (servers, rtype) = _winreg.QueryValueEx(key, 'DhcpNameServer')
  310.         except WindowsError:
  311.             servers = None
  312.  
  313.         if servers:
  314.             self._config_win32_nameservers(servers)
  315.             
  316.             try:
  317.                 (dom, rtype) = _winreg.QueryValueEx(key, 'DhcpDomain')
  318.                 if dom:
  319.                     self._config_win32_domain(servers)
  320.             except WindowsError:
  321.                 pass
  322.             except:
  323.                 None<EXCEPTION MATCH>WindowsError
  324.             
  325.  
  326.         None<EXCEPTION MATCH>WindowsError
  327.         
  328.         try:
  329.             (search, rtype) = _winreg.QueryValueEx(key, 'SearchList')
  330.         except WindowsError:
  331.             search = None
  332.  
  333.         if search:
  334.             self._config_win32_search(search)
  335.         
  336.  
  337.     
  338.     def read_registry(self):
  339.         lm = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
  340.         want_scan = False
  341.         
  342.         try:
  343.             tcp_params = _winreg.OpenKey(lm, 'SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters')
  344.             want_scan = True
  345.         except EnvironmentError:
  346.             tcp_params = _winreg.OpenKey(lm, 'SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP')
  347.         
  348.  
  349.         
  350.         try:
  351.             self._config_win32_fromkey(tcp_params)
  352.         finally:
  353.             tcp_params.Close()
  354.  
  355.         if want_scan:
  356.             interfaces = _winreg.OpenKey(lm, 'SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces')
  357.             
  358.             try:
  359.                 i = 0
  360.                 while True:
  361.                     
  362.                     try:
  363.                         guid = _winreg.EnumKey(interfaces, i)
  364.                         i += 1
  365.                         key = _winreg.OpenKey(interfaces, guid)
  366.                         if not self._win32_is_nic_enabled(lm, guid, key):
  367.                             continue
  368.                         
  369.                         
  370.                         try:
  371.                             self._config_win32_fromkey(key)
  372.                         finally:
  373.                             key.Close()
  374.  
  375.                     continue
  376.                     except EnvironmentError:
  377.                         break
  378.                         continue
  379.                     
  380.  
  381.                     None<EXCEPTION MATCH>EnvironmentError
  382.             finally:
  383.                 interfaces.Close()
  384.  
  385.         lm.Close()
  386.  
  387.     
  388.     def _win32_is_nic_enabled(self, lm, guid, interface_key):
  389.         
  390.         try:
  391.             connection_key = _winreg.OpenKey(lm, 'SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection' % guid)
  392.             
  393.             try:
  394.                 (pnp_id, ttype) = _winreg.QueryValueEx(connection_key, 'PnpInstanceID')
  395.                 if ttype != _winreg.REG_SZ:
  396.                     raise ValueError
  397.                 
  398.                 device_key = _winreg.OpenKey(lm, 'SYSTEM\\CurrentControlSet\\Enum\\%s' % pnp_id)
  399.                 
  400.                 try:
  401.                     (flags, ttype) = _winreg.QueryValueEx(device_key, 'ConfigFlags')
  402.                     if ttype != _winreg.REG_DWORD:
  403.                         raise ValueError
  404.                     
  405.                     return not (flags & 1)
  406.                 finally:
  407.                     device_key.Close()
  408.  
  409.             finally:
  410.                 connection_key.Close()
  411.  
  412.         except (EnvironmentError, ValueError):
  413.             
  414.             try:
  415.                 (nte, ttype) = _winreg.QueryValueEx(interface_key, 'NTEContextList')
  416.                 return nte is not None
  417.             except WindowsError:
  418.                 return False
  419.             except:
  420.                 None<EXCEPTION MATCH>WindowsError
  421.             
  422.  
  423.             None<EXCEPTION MATCH>WindowsError
  424.  
  425.  
  426.     
  427.     def _compute_timeout(self, start):
  428.         now = time.time()
  429.         if now < start:
  430.             if start - now > 1:
  431.                 raise Timeout
  432.             else:
  433.                 now = start
  434.         
  435.         duration = now - start
  436.         if duration >= self.lifetime:
  437.             raise Timeout
  438.         
  439.         return min(self.lifetime - duration, self.timeout)
  440.  
  441.     
  442.     def query(self, qname, rdtype = dns.rdatatype.A, rdclass = dns.rdataclass.IN, tcp = False):
  443.         if isinstance(qname, (str, unicode)):
  444.             qname = dns.name.from_text(qname, None)
  445.         
  446.         if isinstance(rdtype, str):
  447.             rdtype = dns.rdatatype.from_text(rdtype)
  448.         
  449.         if isinstance(rdclass, str):
  450.             rdclass = dns.rdataclass.from_text(rdclass)
  451.         
  452.         qnames_to_try = []
  453.         if qname.is_absolute():
  454.             qnames_to_try.append(qname)
  455.         elif len(qname) > 1:
  456.             qnames_to_try.append(qname.concatenate(dns.name.root))
  457.         
  458.         if self.search:
  459.             for suffix in self.search:
  460.                 qnames_to_try.append(qname.concatenate(suffix))
  461.             
  462.         else:
  463.             qnames_to_try.append(qname.concatenate(self.domain))
  464.         all_nxdomain = True
  465.         start = time.time()
  466.         for qname in qnames_to_try:
  467.             if self.cache:
  468.                 answer = self.cache.get((qname, rdtype, rdclass))
  469.                 if answer:
  470.                     return answer
  471.                 
  472.             
  473.             request = dns.message.make_query(qname, rdtype, rdclass)
  474.             if self.keyname is not None:
  475.                 request.use_tsig(self.keyring, self.keyname)
  476.             
  477.             request.use_edns(self.edns, self.ednsflags, self.payload)
  478.             response = None
  479.             nameservers = self.nameservers[:]
  480.             backoff = 0.1
  481.             while response is None:
  482.                 if len(nameservers) == 0:
  483.                     raise NoNameservers
  484.                 
  485.                 for nameserver in nameservers[:]:
  486.                     timeout = self._compute_timeout(start)
  487.                     
  488.                     try:
  489.                         if tcp:
  490.                             response = dns.query.tcp(request, nameserver, timeout, self.port)
  491.                         else:
  492.                             response = dns.query.udp(request, nameserver, timeout, self.port)
  493.                     except (socket.error, dns.exception.Timeout):
  494.                         response = None
  495.                         continue
  496.                     except dns.query.UnexpectedSource:
  497.                         response = None
  498.                         continue
  499.                     except dns.exception.FormError:
  500.                         nameservers.remove(nameserver)
  501.                         response = None
  502.                         continue
  503.  
  504.                     rcode = response.rcode()
  505.                     if rcode == dns.rcode.NOERROR or rcode == dns.rcode.NXDOMAIN:
  506.                         break
  507.                     
  508.                     if rcode != dns.rcode.SERVFAIL:
  509.                         nameservers.remove(nameserver)
  510.                     
  511.                     response = None
  512.                 
  513.                 if response is not None:
  514.                     break
  515.                 
  516.                 if len(nameservers) > 0:
  517.                     timeout = self._compute_timeout(start)
  518.                     sleep_time = min(timeout, backoff)
  519.                     backoff *= 2
  520.                     time.sleep(sleep_time)
  521.                     continue
  522.             if response.rcode() == dns.rcode.NXDOMAIN:
  523.                 continue
  524.             
  525.             all_nxdomain = False
  526.         
  527.         if all_nxdomain:
  528.             raise NXDOMAIN
  529.         
  530.         answer = Answer(qname, rdtype, rdclass, response)
  531.         if self.cache:
  532.             self.cache.put((qname, rdtype, rdclass), answer)
  533.         
  534.         return answer
  535.  
  536.     
  537.     def use_tsig(self, keyring, keyname = None):
  538.         self.keyring = keyring
  539.         if keyname is None:
  540.             self.keyname = self.keyring.keys()[0]
  541.         else:
  542.             self.keyname = keyname
  543.  
  544.     
  545.     def use_edns(self, edns, ednsflags, payload):
  546.         if edns is None:
  547.             edns = -1
  548.         
  549.         self.edns = edns
  550.         self.ednsflags = ednsflags
  551.         self.payload = payload
  552.  
  553.  
  554. default_resolver = None
  555.  
  556. def get_default_resolver():
  557.     global default_resolver
  558.     if default_resolver is None:
  559.         default_resolver = Resolver()
  560.     
  561.     return default_resolver
  562.  
  563.  
  564. def query(qname, rdtype = dns.rdatatype.A, rdclass = dns.rdataclass.IN, tcp = False):
  565.     return get_default_resolver().query(qname, rdtype, rdclass, tcp)
  566.  
  567.  
  568. def zone_for_name(name, rdclass = dns.rdataclass.IN, tcp = False, resolver = None):
  569.     if isinstance(name, (str, unicode)):
  570.         name = dns.name.from_text(name, dns.name.root)
  571.     
  572.     if resolver is None:
  573.         resolver = get_default_resolver()
  574.     
  575.     if not name.is_absolute():
  576.         raise NotAbsolute, name
  577.     
  578.     while None:
  579.         
  580.         try:
  581.             answer = resolver.query(name, dns.rdatatype.SOA, rdclass, tcp)
  582.             return name
  583.         continue
  584.         except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
  585.             
  586.             try:
  587.                 name = name.parent()
  588.             except dns.name.NoParent:
  589.                 raise NoRootSOA
  590.             except:
  591.                 None<EXCEPTION MATCH>dns.name.NoParent
  592.             
  593.  
  594.             None<EXCEPTION MATCH>dns.name.NoParent
  595.         
  596.  
  597.         return None
  598.  
  599.